手写dubbo 9-SPI实现
条评论博客中代码地址:https://github.com/farliu/farpc.git
项目结构介绍
本节涉及博客中代码的三个module,farpc-registry(服务治理)、farpc-cluster(集群管理),farpc-common。
本章重点就是farpc-common。而SPI具体实现方案就是ExtensionLoader。本章大部分代码都从dubbo源码中提取。
我们在贴代码之前还是讲讲涉及到的类前后推理的逻辑。ExtensionLoader为SPI重要实现类,本章实现的简单的SPI其实有这个类就够了。但是在dubbo中还提供了两个辅助类,我觉得有必要就也加进来一起聊聊,一个是FarSPI注解,一个是Holder。
SPI实现
本章代码量有点大,下面贴代码会导致篇幅过长,我们针对涉及的几个都分别解析一下,具体代码大家可以上github自己clone。我们对照项目结构一个个分析。
FarSPI
FarSPI注解用来标注接口的默认配置对象。
Holder
Holder用来包装对象实例,上两章中有提到dubbo中很多地方用到了double-check-lock,它虽然能保证并发,但是出现重排序时,调用者拿到的对象可能是一个未初始化的地址。所以使用Holder对其包装,利用volatile保证可见性。
ExtensionLoader
ExtensionLoader做SPI重点,代码中都有标注有注释,应该很清楚。这里看一下怎么使用。
1 | ILoadbalance extension = ExtensionLoader.getExtensionLoader(ILoadbalance.class).getExtension(loadbalance); |
Property、PropertyUtil
这两个类是为了读取用户的配置写的,dubbo会解析xml,我这里由用户在application.properties中指定。
使用
SPI其实就靠上面几个类就能运行了,现在说说怎么使用,我在ExtensionLoader中读取META-INF/farpc/下面的文件,我们需要将SPI的配置放在该文件夹下,文件名字为接口的全路径。
例如:让SPI创建ILoadbalance的对象。在之前我们实现了两个ILoadbalance的方案RoundLoadBalanceImpl、RandomLoadbalanceImpl。
以及在之前我们实现了两种注册中心,也可以交由SPI初始化对象
测试
1 | @Test |
在项目中优雅使用
SPI扩展负载均衡
在项目启动时,Property类会加载用户的配置。我在代码中是由一个LoadbalanceFactory去调用SPI的。就是类似dubbo SPI的自适应机制,在dubbo中自适应机制是由dubbo生成代理类去完成对实现类调用的路由,我这里是直接写死由Factory去管理。
在之前讲述服务发现的代码时,我也留下了伏笔AbstractRegistrar,那么这一节,我们可以在AbstractRegistrar中调用LoadbalanceFactory。例如
1 | public abstract class AbstractRegistrar implements IRegistrar { |
然后在配置文件application.properties中,指定loadbalance方式,就可以由Factory路由要你需要的负载均衡算法。如下:
1 | farpc.cluster.loadbalance=random |
SPI扩展注册中心
按照上面的设计模式,我们其实还可以管理注册中心、调用协议、序列化方式,等等等等….例如,我们在使用SPI加载注册中心。
注册中心的地址和端口,一般也是不会变的,我也把它放在配置文件中,在AbstractRegistrar的构造中将注册中心的地址传给ZookeeperRegistrarImpl和RedisRegistrarImpl,交由他们各自去实现,并AbstractRegistrar来调用。
1 | public abstract class AbstractRegistrar implements IRegistrar { |
application.properties
1 | farpc.registry.protocol=zookeeper |
完成上面的优化,我们调用时就可以极其简洁,并且新拓展其他注册中心也只要实现AbstractRegistrar的抽象接口就行,对已有的代码没有任何侵入。
1 | @Test |
这一节没有对各个类的代码讲述,可能有点跳跃。不过代码很简单,稍微瞥一眼就行。这个系列,我们实现的RPC调用,意义在于了解整个调用过程。
- 本文链接:https://www.ofcoder.com/2019/10/20/java/%E6%89%8B%E5%86%99dubbo%209-SPI%E5%AE%9E%E7%8E%B0/
- 版权声明:Copyright © 并发笔记 - ofcoder.com. Author by far.
分享